package tech.dongliang.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.web.filter.DelegatingFilterProxy;
import tech.dongliang.shiro.*;

import javax.servlet.Filter;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author jack
 */
@Configuration
public class ShiroConfig {
    private static final long SESSION_TIMEOUT = 1800000L;

    @Bean("defaultAdvisorAutoProxyCreator")
    @DependsOn("lifecycleBeanPostProcessor")
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        //指定强制使用cglib为action创建代理对象
        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
        return defaultAdvisorAutoProxyCreator;
    }


    @Bean("lifecycleBeanPostProcessor")
    public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    @Bean("delegatingFilterProxy")
    public FilterRegistrationBean delegatingFilterProxy() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        DelegatingFilterProxy proxy = new DelegatingFilterProxy();
        proxy.setTargetFilterLifecycle(true);
        proxy.setTargetBeanName("shiroFilter");
        filterRegistrationBean.setFilter(proxy);
        return filterRegistrationBean;
    }

    /**
     * ShiroDialect，为了在thymeleaf里使用shiro的标签的bean
     *
     * @return
     */
    @Bean
    public ShiroDialect shiroDialect() {
        return new ShiroDialect();
    }

    @Bean
    ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager, ShiroService shiroService) {
        ShiroFilterFactoryBean shiroFilter  = new ShiroFilterFactoryBean();
        shiroFilter .setSecurityManager(securityManager);
        shiroFilter .setLoginUrl("/login");
        shiroFilter .setSuccessUrl("/index");
        shiroFilter .setUnauthorizedUrl("/403");
        Map<String, Filter> filterMap = new LinkedHashMap<>();
        filterMap.put("authc", new ShiroLoginFilter());
        filterMap.put("perms", new ShiroPermsFilter());
        shiroFilter .setFilters(filterMap);
//        LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
//        filterChainDefinitionMap.put("/css/**", "anon");
//        filterChainDefinitionMap.put("/js/**", "anon");
//        filterChainDefinitionMap.put("/images/**", "anon");
//        filterChainDefinitionMap.put("/lib/**", "anon");
//        filterChainDefinitionMap.put("/logout", "logout");
//        filterChainDefinitionMap.put("/**", "authc");
//        shiroFilter .setFilterChainDefinitionMap(filterChainDefinitionMap);
        shiroFilter.setFilterChainDefinitionMap(shiroService.loadFilterChainDefinitions());
        return shiroFilter ;
    }


    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //设置realm.
        securityManager.setRealm(sysUserRealm());
        //注入session管理器
        securityManager.setSessionManager(sessionManager());
        //注入缓存管理器
        securityManager.setCacheManager(hazelcastCacheManager());
        return securityManager;
    }

    @Bean
    SysUserRealm sysUserRealm() {
        SysUserRealm userRealm = new SysUserRealm();
        return userRealm;
    }

    @Bean
    public SpringCacheManagerWrapper hazelcastCacheManager() {
        SpringCacheManagerWrapper cacheManager = new SpringCacheManagerWrapper();
        return cacheManager;
    }

    /**
     * shiro session的管理
     */
    @Bean
    public DefaultWebSessionManager sessionManager() {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        sessionManager.setGlobalSessionTimeout(SESSION_TIMEOUT);
        sessionManager.setSessionDAO(sessionDAO());
        sessionManager.setSessionListeners(Arrays.asList(new AppSessionListener()));
        return sessionManager;
    }

    @Bean
    public EnterpriseCacheSessionDAO sessionDAO() {
        EnterpriseCacheSessionDAO sessionDAO = new EnterpriseCacheSessionDAO();
        return sessionDAO;
    }

    //    @Bean
//    public ShiroLoginFilter shiroLoginFilter() {
//        ShiroLoginFilter shiroLoginFilter = new ShiroLoginFilter();
//        return shiroLoginFilter;
//    }
//
//    @Bean
//    public ShiroPermsFilter shiroPermsFilter() {
//        ShiroPermsFilter shiroPermsFilter = new ShiroPermsFilter();
//        return shiroPermsFilter;
//    }
//    @Bean
//    public FilterRegistrationBean shiroLoginFilteRegistration(ShiroLoginFilter filter) {
//        FilterRegistrationBean registration = new FilterRegistrationBean(filter);
//        registration.setEnabled(false);
//        return registration;
//    }
//
//
//    @Bean
//    public FilterRegistrationBean shiroPermsFilterRegistration(ShiroPermsFilter filter) {
//        FilterRegistrationBean registration = new FilterRegistrationBean(filter);
//        registration.setEnabled(false);
//        return registration;
//    }

}
